/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"

#include "../dir_monitor/head.h"
#include "../dynamic/head.h"
#include "../thread/head.h"
#include "../select/head.h"
#include "../socket/head.h"
#include "../macro/head.h"
#include "../misc/head.h"
#include "../time/head.h"
#include "../file/head.h"
#include "../sync/head.h"
#include "../crt/head.h"
#include "mgr.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 

namespace xos
{

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static xos_container::i_container * container_ptr = 0;
    static mgr * mgr_ptr = 0;

    static char exe_path_array[4096] = { 0 };
    static i_misc * misc_ptr = 0;
    static i_crt * crt_ptr = 0;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    mgr::mgr()
    {
    }

    mgr::~mgr()
    {
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int mgr::static_init( xos_container::i_container * pContainer, i_xos ** ppv )
    {
        return xos_stl::static_init_module( pContainer, ppv, container_ptr, mgr_ptr );
    }

    xos_container::i_container * mgr::container()
    {
        return container_ptr;
    }

    i_xos * mgr::get()
    {
        return mgr_ptr;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    //
    // 需要释放
    // 
    i_dir_monitor * mgr::dir_monitor()
    {
        dir_monitor_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_dynamic * mgr::dynamic()
    {
        dynamic_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_thread * mgr::thread()
    {
        thread_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_time * mgr::tm()
    {
        time_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_file * mgr::file()
    {
        file_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_dir * mgr::dir()
    {
        dir_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_socket * mgr::socket()
    {
        socket_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_select * mgr::select()
    {
        select_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_event * mgr::event()
    {
        event_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_lock * mgr::mutex()
    {
        mutex_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    i_lock * mgr::spin()
    {
        spin_impl::T * pRet = 0;
        xos_stl::init_pool_item( pRet );
        return pRet;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    //
    // 不用释放
    // 
    i_misc * mgr::misc()
    {
        return misc_ptr;
    }

    i_crt * mgr::crt()
    {
        return crt_ptr;
    }

    // 
    // get exe path
    // 
    const char * mgr::exe_path()
    {
        return exe_path_array;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int mgr::init()
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = dir_monitor_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = dynamic_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = thread_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = socket_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = select_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = misc_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = time_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = dir_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = file_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = event_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = mutex_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = spin_impl::init_all();
        }

        if( 0 == ret )
        {
            ret = crt_impl::init_all();
        }

        /////////////////////////////////////////////////////////////////////////////////
        // 
        // 创建常驻对象
        // 

        if( 0 == ret )
        {
            misc_impl::T * pT = 0;
            xos_stl::init_pool_item( pT );
            misc_ptr = pT;
        }

        if( 0 == ret )
        {
            crt_impl::T * pT = 0;
            xos_stl::init_pool_item( pT );
            crt_ptr = pT;
        }

        if( 0 == ret )
        {
            misc()->get_process_path( exe_path_array, sizeof( exe_path_array ), 0 );
        }

        return ret;
    }

    int mgr::term()
    {
        int nRet = 0;

        // 
        // 释放常驻对象
        // 
        xos_stl::release_interface( misc_ptr );
        xos_stl::release_interface( crt_ptr );

        // 
        // thread, should release second
        // 
        thread_impl::term_all();

        // 
        // dir
        // 
        dir_monitor_impl::term_all();

        // 
        // select
        // 
        select_impl::term_all();

        // 
        // socket
        // 
        socket_impl::term_all();

        // 
        // file path
        //
        dir_impl::term_all();
        file_impl::term_all();

        // 
        // sync
        // 
        event_impl::term_all();
        mutex_impl::term_all();
        spin_impl::term_all();

        // 
        // misc
        //
        misc_impl::term_all();

        // 
        // time
        //
        time_impl::term_all();

        // 
        // crt
        // 
        crt_impl::term_all();

        // 
        // dynamic
        // 
        dynamic_impl::term_all();

        // 
        // xos impl
        // 
        container_ptr = 0;
        mgr_ptr = 0;

        return nRet;
    }

    int mgr::put_back_to_pool()
    {
        int ret = 0;
        delete this;
        return ret;
    }

} // xos
